bitkeeper revision 1.65 (3e536858YdNPGFSv3J35Fl8zAGLJjQ)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 19 Feb 2003 11:19:52 +0000 (11:19 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 19 Feb 2003 11:19:52 +0000 (11:19 +0000)
sched.h, xen_block.c, domain.c:
  Now have per-domain IO completion queue.

xen-2.4.16/common/domain.c
xen-2.4.16/drivers/block/xen_block.c
xen-2.4.16/include/xeno/sched.h

index 428927a28d096614b7a4fd773515fa2f934339ac..d3f9ef2640cc3a6ad64368655a658688bb0457f0 100644 (file)
@@ -49,6 +49,9 @@ struct task_struct *do_newdomain(void)
     p->active_mm  = &p->mm;
     p->num_net_vifs = 0;
 
+    INIT_LIST_HEAD(&p->io_done_queue);
+    spin_lock_init(&p->io_done_queue_lock);
+
     /*
      * KAF: Passing in newdomain struct to this function is gross!
      * Therefore, for now we just allocate the single blk_ring
index 449eefe6a7fb61f8475c2ff128a9be70adc40e5a..0d98cfbab63f8def4fe6ccc16f050851e39394dd 100644 (file)
@@ -36,10 +36,8 @@ blk_request_t blk_request_list[XEN_BLK_REQUEST_LIST_SIZE];
 
 struct list_head free_queue;          /* unused requests */
 struct list_head pending_queue;       /* waiting for hardware */
-struct list_head io_done_queue;       /* request completed. send to guest os */
 spinlock_t free_queue_lock;
 spinlock_t pending_queue_lock;
-spinlock_t io_done_queue_lock;
 
 /* some definitions */
 void dumpx (char *buffer, int count);
@@ -63,36 +61,37 @@ void end_block_io_op(struct buffer_head * bh)
     /* struct list_head *list;*/
     blk_request_t *blk_request = NULL;
     unsigned long flags; /* irq save */
-    
+    struct task_struct *p;
+
     if (XEN_BLK_DEBUG)  
        printk(XEN_BLK_DEBUG_LEVEL "XEN end_block_io_op,  bh: %lx\n",
               (unsigned long)bh);
     
     spin_lock_irqsave(&pending_queue_lock, flags);
-    blk_request = (blk_request_t *)bh->b_xen_request;
-    
-    if (blk_request == NULL) {
-       printk (KERN_ALERT
-               "   block io interrupt received for unknown buffer [0x%lx]\n",
-               (unsigned long) bh);
-       spin_unlock_irqrestore(&pending_queue_lock, flags);
-       BUG();
-       return;
-    }
-    
+    if ( (blk_request = (blk_request_t *)bh->b_xen_request) == NULL) 
+        goto bad_interrupt;
     list_del(&blk_request->queue);
-    spin_unlock_irqrestore(&pending_queue_lock, flags);
-    
-    spin_lock_irqsave(&io_done_queue_lock, flags);
-    list_add_tail(&blk_request->queue, &io_done_queue);
+    spin_unlock(&pending_queue_lock);
     
+    p = blk_request->domain;
+
+    spin_lock(&p->io_done_queue_lock);
+    list_add_tail(&blk_request->queue, &p->io_done_queue);
     /* enqueue work for 'flush_blk_queue' handler */
-    cpu_mask = mark_hyp_event(blk_request->domain, _HYP_EVENT_BLK_RX);
-    spin_unlock_irqrestore(&io_done_queue_lock, flags);
+    cpu_mask = mark_hyp_event(p, _HYP_EVENT_BLK_RX);
+    spin_unlock_irqrestore(&p->io_done_queue_lock, flags);
     
     /* now kick the hypervisor */
     hyp_event_notify(cpu_mask); 
     return;
+
+ bad_interrupt:
+    printk (KERN_ALERT
+            "   block io interrupt received for unknown buffer [0x%lx]\n",
+            (unsigned long) bh);
+    spin_unlock_irqrestore(&pending_queue_lock, flags);
+    BUG();
+    return;
 }
 
 /*
@@ -104,23 +103,24 @@ void end_block_io_op(struct buffer_head * bh)
 
 void flush_blk_queue(void)
 {
+    struct task_struct *p = current;
     blk_request_t *blk_request;
     int position = 0;
     blk_ring_t *blk_ring;
     unsigned long flags;
     int loop;
     
-    spin_lock_irqsave(&io_done_queue_lock, flags);
-    clear_bit(_HYP_EVENT_BLK_RX, &current->hyp_events);
+    spin_lock_irqsave(&p->io_done_queue_lock, flags);
+    clear_bit(_HYP_EVENT_BLK_RX, &p->hyp_events);
     
-    while (!list_empty(&io_done_queue)) {
-
-       blk_request = list_entry(io_done_queue.next, blk_request_t, queue);
-       list_del (&blk_request->queue);
-       spin_unlock_irqrestore(&io_done_queue_lock, flags);
+    while ( !list_empty(&p->io_done_queue) )
+    {
+       blk_request = list_entry(p->io_done_queue.next, blk_request_t, queue);
+       list_del(&blk_request->queue);
+       spin_unlock_irqrestore(&p->io_done_queue_lock, flags);
        
        /* place on ring for guest os */ 
-       blk_ring = blk_request->domain->blk_ring_base;
+       blk_ring = p->blk_ring_base;
        position = blk_ring->brx_prod;
 
        if (XEN_BLK_DEBUG)  
@@ -131,19 +131,19 @@ void flush_blk_queue(void)
        blk_ring->brx_prod = BLK_RX_RING_INC(blk_ring->brx_prod);
 
        /* notify appropriate guest os */
-       set_bit(_EVENT_BLK_RX, &blk_request->domain->shared_info->events);
+       set_bit(_EVENT_BLK_RX, &p->shared_info->events);
        
        /* free the buffer header allocated in do_block_io_op */
-       if (blk_request->bh)
+       if ( blk_request->bh )
            kfree(blk_request->bh); 
 
        spin_lock_irqsave(&free_queue_lock, flags);
        list_add_tail(&blk_request->queue, &free_queue);
        spin_unlock_irqrestore(&free_queue_lock, flags);
 
-       spin_lock_irqsave(&io_done_queue_lock, flags);
+       spin_lock_irqsave(&p->io_done_queue_lock, flags);
     }
-    spin_unlock_irqrestore(&io_done_queue_lock, flags);
+    spin_unlock_irqrestore(&p->io_done_queue_lock, flags);
 
 
     /* XXX SMH: below is ugly and dangerous -- fix */
@@ -160,15 +160,15 @@ void flush_blk_queue(void)
      * at domain 0 every time (although we might want to special
      * case domain 0);
      */
-    for (loop = 0; loop < XEN_BLOCK_MAX_DOMAINS; loop++) {
-
+    for ( loop = 0; loop < XEN_BLOCK_MAX_DOMAINS; loop++ )
+    {
        int domain = pending_work & (1 << loop);
 
-       if (domain) {
-
+       if ( domain ) 
+        {
            struct task_struct *mytask = current;
 
-           while (mytask->domain != loop)
+           while ( mytask->domain != loop )
                mytask = mytask->next_task;
 
            pending_work = pending_work & !(1 << loop);
@@ -421,9 +421,13 @@ static void dump_blockq(u_char key, void *dev_id, struct pt_regs *regs)
     dump_queue(&pending_queue, "PENDING QUEUE"); 
     spin_unlock_irqrestore(&pending_queue_lock, flags);
 
+#if 0
     spin_lock_irqsave(&io_done_queue_lock, flags);
     dump_queue(&io_done_queue, "IO DONE QUEUE"); 
     spin_unlock_irqrestore(&io_done_queue_lock, flags);
+#else
+    printk("FIXME: IO_DONE_QUEUE IS NOW PER DOMAIN!!\n");
+#endif
 
     return; 
 }
@@ -443,11 +447,9 @@ void initialize_block_io (){
     
     INIT_LIST_HEAD(&free_queue);
     INIT_LIST_HEAD(&pending_queue);
-    INIT_LIST_HEAD(&io_done_queue);
     
     spin_lock_init(&free_queue_lock);
     spin_lock_init(&pending_queue_lock);
-    spin_lock_init(&io_done_queue_lock);
     
     for (loop = 0; loop < XEN_BLK_REQUEST_LIST_SIZE; loop++)
     {
index 75b7959ee11be6bb83c81901bf2d4da6d5467337..c77c0e835ef64fa5c63fa8eb4df3895a92c54798 100644 (file)
@@ -70,13 +70,15 @@ struct task_struct {
     struct list_head pg_head;
     unsigned int tot_pages;
 
-    /* Pointer to this guest's virtual interfaces. */
-    /* network */
+    /* Network I/O */
     net_ring_t *net_ring_base;
     net_vif_t *net_vif_list[MAX_GUEST_VIFS];
     int num_net_vifs;
-    /* block io */
+
+    /* Block I/O */
     blk_ring_t *blk_ring_base;
+    struct list_head io_done_queue;
+    spinlock_t io_done_queue_lock;
 
     int has_cpu, policy, counter;